package fr.neyb.bernouilli.problem018;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.regex.Pattern;

import fr.neyb.bernouilli.common.tools.MyArrays;
import fr.neyb.bernouilli.common.tools.MyArrays.Convertor;

public class ValuesTriangle {

	private final static Pattern splitter = Pattern.compile(" ",
			Pattern.LITERAL);
	private final static Convertor<UnmodifiableNode, Node> NodeFixer = new Convertor<UnmodifiableNode, Node>() {
		@Override
		public UnmodifiableNode getValue(Node o) {
			return o.getUnmodifiableNode();
		}
	};

	public static ValuesTriangle parse(Reader r) throws IOException {
		ArrayList<Node[]> content = new ArrayList<>();
		{
			BufferedReader br = new BufferedReader(r);
			String line;
			int lineNum = 0;
			String[] elements;
			Node[] elementsAsNode;

			while ((line = br.readLine()) != null) {
				elements = splitter.split(line);
				elementsAsNode = new Node[elements.length];
				for (int i = 0; i < elements.length; i++) {
					elementsAsNode[i] = new Node(Integer.parseInt(elements[i]));
					if (lineNum > 0) {
						Node[] prevNode = content.get(lineNum - 1);
						if (i > 0)
							elementsAsNode[i].addParent(prevNode[i - 1]);
						if (i <= prevNode.length - 1)
							elementsAsNode[i].addParent(prevNode[i]);
					}
				}
				content.add(elementsAsNode);
				++lineNum;
			}

			for (int i = 0; i < content.size(); ++i) {
				content.set(i, MyArrays.convertArray(NodeFixer,
						content.get(i), UnmodifiableNode.class));
			}
		}
		return new ValuesTriangle(content.toArray(new UnmodifiableNode[content
				.size()][]));
	}

	private final Node[][] content;

	private ValuesTriangle(UnmodifiableNode[][] content) {
		this.content = content;
	}

	public Node[][] getContent() {
		return content;
	}
}
